<?php
/**
 * @package       system
 * @subpackage    jsCall
 */
/**
 * A JsCall is a set of method calls serialized in a JSON format
 * that will normally be sent as a js ajax response. 
 * The caller js will then execute each of the commands.
 * The result is a similar to a RMI, calling js methods from php.
 * Althought, the response is not sent back to the php script.
 * 
 * Usage examples: {@link JsCallTest::testShouldBuildValidJSON()} 
 * Its important to see the {@link http://essaylibrarydocs/jsapi/JsonC.html JsonC javascript class} to better understand this architecture.
 * @see JsCommand
 */
class JsCall {

  /**
   * The array of commands that compose this call. 
   *
   * @var array
   */
  private $arCommand;
  /**
   * A reference to the last command addes to the array of commands.
   * Used to further add parameters to this command. 
   * 
   * @var JsCommand
   */
  private $actualCommand;

  private $feedbackMessage;
  /**
   * @return JsCall
   */
  static function build() {
  	return new JsCall;
  }
  
  /**
   * @return JsCall
   */
  function & addCommand($controller,$action) {
  	$this->actualCommand = new JsCommand($controller,$action,$this);
  	$this->arCommand[] = $this->actualCommand;
  	return $this;
  }
  
  /**
   * Used to add parameters already formated with json_encode or json strings.
   * 
   * @return JsCall
   */
  function addJsonParam($name,$param) {
    $this->actualCommand->addJsonParam($name,$param);
    return $this;	
  }
  
  /**
   * 
   * @return JsCall
   */
  function addPHPParam($name,$param) {
    $this->actualCommand->addPHPParam($name,$param);
    return $this;	
  }
  
  /**
   * Returns a JSON string representation of this call. 
   * This call is generally executed by the js method JsonC::receiveJsonCall
   * 
   * @return string
   */
  function toJson() {
    if($this->feedbackMessage) {
        $this
          ->addCommand('UtilC','showFeedback')
          ->addPHPParam('message',$this->feedbackMessage);
    }
  	$json = "{\"commands\":[\n";
  	$comma = '';
    foreach($this->arCommand as $command) {
      $json .= $comma.$command->toJson();
      $comma = ',';
    }
  	$json .= "]}";
  	return $json;
  }
  
  ################################################### SHORTCUTS
  
  /**
   * Assemble the JS command that shows the feedback message on screen. 
   * Calls the JS UtilC::showFeedback method passing the message.
   * @param string message The message to be shown, may include html. 
   * @return JsCall
   */
  public function showFeedback($message = null) {
      $this->addFeedback($message);
      return $this;
  }

  public function addFeedback($message) {
      $this->feedbackMessage .= ($this->feedbackMessage ? "<br/>\n" : '').$message;
      return $this;
  }
  
  /**
   * @return JsCall
   */
  public function displayDialog($data) {
    return 
      $this
        ->addCommand('UtilC','displayDialog')
        ->addPHPParam('data',$data);
  }
  
  public function closeDialog() {
    return 
      $this
        ->addCommand('UtilC','closeDialog');
  }
  
  /**
   * Assemble the JS command that shows the form error. 
   * Calls the JS JoinC::showFormError method passing the parameters.
   * @param string fieldName The dom id of the field where to show the message. 
   * @param string message The message to be shown, may include html. 
   * @return JsCall
   */
  public function showFormError($fieldName,$message) {
    return 
      $this->addCommand('JoinC','showFormError')
  	      ->addPHPParam('fieldName',$fieldName)
  	      ->addPHPParam('message',$message);
  }
  
}
?>